use {
    super::{common::AppState, error_handle},
    axum::{
        extract::{self, Path, Query, State},
        http::StatusCode,
        response::Json,
    },
    repository::model::dapp_contract::DAppContract,
    serde::{self, Deserialize},
    tron::{base, service},
    sqlx::{MySql, Pool},
};

#[derive(serde::Deserialize)]
pub struct TransferTokenApiParams {
    chain: String,
    payer: String,
    from: String,
    to: String,
    amount: u64,
    contract: String,
    decimals: u8,
}

pub async fn transfer_token(
    State(state): State<AppState>,
    extract::Json(body): extract::Json<TransferTokenApiParams>,
) -> Result<Json<String>, (StatusCode, String)> {
    let chain = body.chain;
    let payer = body.payer;
    let from = body.from;
    let to = body.to;
    let amount = body.amount;
    let contract = body.contract;
    let decimals = body.decimals;
    let amount_str = amount.to_string();

    let tx_hash = match chain.as_str() {
        "TRON" => {
            let client = tron::base::client::build_client(commons::common::ENV);
            tron::service::token::transfer_token(&client, &contract, &payer, &from, &to, amount as u128)
            .await.map_err(error_handle::internal_error)?
        },
        _ => {
            String::from("Unsupported chains")
        },
    };

    Ok(Json::from(tx_hash))
}

#[derive(Debug, Deserialize)]
#[allow(dead_code)]
pub struct BalanceTokenParams {
    account: String,
    contract: String,
}

pub async fn balance_token(
    State(state): State<AppState>,
    Query(params): Query<BalanceTokenParams>,
) -> Result<Json<String>, (StatusCode, String)> {
    let client = base::client::build_client(state.env);
    let contract = params.contract;
    let acct = params.account;
    let balance = service::token::token_balance(&client, contract.as_str(), acct.as_str()).await
        .map_err(error_handle::internal_error)?;

    Ok(Json::from(balance))
}
